<template>
	<view v-if="showPopup" class="uni-popup" :class="[popupstyle, isDesktop ? 'fixforpc-z-index' : '']" @touchmove.stop.prevent="clear">
		<uni-transition v-if="maskShow" class="uni-mask--hook" mode-class="fade" :styles="maskClass" :duration="duration" :show="showTrans" @click="onTap" />
		<uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap">
			<view class="uni-popup__wrapper-box" @click.stop="clear"><slot /></view>
		</uni-transition>
		<!-- #ifdef H5 -->
		<keypress v-if="maskShow" @esc="onTap" />
		<!-- #endif -->
	</view>
</template>

<script>
import popup from './popup.js'
// #ifdef H5
import keypress from './keypress.js'
// #endif


/**
 * PopUp 弹出层
 * @description 弹出层组件，为了解决遮罩弹层的问题
 * @tutorial https://ext.dcloud.net.cn/plugin?id=329
 * @property {String} type = [top|center|bottom] 弹出方式
 * 	@value top 顶部弹出
 * 	@value center 中间弹出
 * 	@value bottom 底部弹出
 * 	@value message 消息提示
 * 	@value dialog 对话框
 * 	@value share 底部分享示例
 * @property {Boolean} animation = [ture|false] 是否开启动画
 * @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
 * @event {Function} change 打开关闭弹窗触发，e={show: false}
 */

export default {
	name: 'UniPopup',
	components: {
		// #ifdef H5
		keypress
		// #endif
	},
	props: {
		// 开启动画
		animation: {
			type: Boolean,
			default: true
		},
		// 弹出层类型，可选值，top: 顶部弹出层；bottom：底部弹出层；center：全屏弹出层
		// message: 消息提示 ; dialog : 对话框
		type: {
			type: String,
			default: 'center'
		},
		// maskClick
		maskClick: {
			type: Boolean,
			default: true
		}
	},
	provide() {
		return {
			popup: this
		}
	},
	mixins: [popup],
	watch: {
		/**
		 * 监听type类型
		 */
		type: {
			handler: function(type) {
				this[this.config[type]](true)
			},
			immediate: true
		},
		isDesktop: {
			handler: function(newVal) {
				this[this.config[this.type]](true)
			},
			immediate: true
		},
		/**
		 * 监听遮罩是否可点击
		 * @param {Object} val
		 */
		maskClick: {
			handler: function(val) {
				this.mkclick = val
			},
			immediate: true
		}
	},
	data() {
		return {
			duration: 300,
			ani: [],
			showPopup: false,
			showTrans: false,
			popupWidth: 0,
			popupHeight: 0,
			config:{
				// 顶部弹出
				top: 'top',
				// 底部弹出
				bottom: 'bottom',
				// 居中弹出
				center: 'center',
			},
			maskClass: {
				position: 'fixed',
				bottom: 0,
				top: 0,
				left: 0,
				right: 0,
				backgroundColor: 'rgba(0, 0, 0, 0.4)'
			},
			transClass: {
				position: 'fixed',
				left: 0,
				right: 0
			},
			maskShow: true,
			mkclick: true,
			popupstyle: this.isDesktop ? 'fixforpc-top' : 'top'
		}
	},
	computed: {
		isDesktop() {
			return this.popupWidth >= 500 && this.popupHeight >= 500
		}
	},
	mounted() {
		const fixSize = () => {
			const {
				windowWidth,
				windowHeight,
				windowTop
			} = uni.getSystemInfoSync()
			this.popupWidth = windowWidth
			this.popupHeight = windowHeight + windowTop
		}
		fixSize()
		// #ifdef H5
		window.addEventListener('resize', fixSize)
		this.$once('hook:beforeDestroy', () => {
			window.removeEventListener('resize', fixSize)
		})
		// #endif
	},
	created() {
		this.mkclick = this.maskClick
		if (this.animation) {
			this.duration = 300
		} else {
			this.duration = 0
		}
	},
	methods: {
		clear(e) {
			// TODO nvue 取消冒泡
			e.stopPropagation()
		},
		open(direction) {
			if(!(direction && ['top','center','bottom'].indexOf(direction) !== -1)){
				direction = this.type
			}
			this[this.config[direction]]()
			// clearTimeout(this.msgtimer)
			// this.msgtimer = setTimeout(() => {
			// 	this.customOpen && this.customOpen()
			// }, 100)
			this.$emit('change', {
				show: true,
				type: this.type
			})
		},
		close(type) {
			this.showTrans = false
			this.$emit('change', {
				show: false,
				type: this.type
			})
			clearTimeout(this.timer)
			// // 自定义关闭事件
			// this.customOpen && this.customClose()
			this.timer = setTimeout(() => {
				this.showPopup = false
			}, 300)
		},
		onTap() {
			if (!this.mkclick) return
			this.close()
		},
		/**
		 * 顶部弹出样式处理
		 */
		top(type) {
			this.popupstyle = this.isDesktop ? 'fixforpc-top' : 'top'
			this.ani = ['slide-top']
			this.transClass = {
				position: 'fixed',
				left: 0,
				right: 0
			}
			// TODO 兼容 type 属性 ，后续会废弃
			if(type) return
			this.showPopup = true
			this.showTrans = true
		},
		/**
		 * 底部弹出样式处理
		 */
		bottom(type) {
			this.popupstyle = 'bottom'
			this.ani = ['slide-bottom']
			this.transClass = {
				position: 'fixed',
				left: 0,
				right: 0,
				bottom: 0
			}
			// TODO 兼容 type 属性 ，后续会废弃
			if(type) return
			this.showPopup = true
			this.showTrans = true
		},
		/**
		 * 中间弹出样式处理
		 */
		center(type) {
			this.popupstyle = 'center'
			this.ani = ['zoom-out', 'fade']
			this.transClass = {
				position: 'fixed',
				/* #ifndef APP-NVUE */
				display: 'flex',
				flexDirection: 'column',
				/* #endif */
				bottom: 0,
				left: 0,
				right: 0,
				top: 0,
				justifyContent: 'center',
				alignItems: 'center'
			}
			// TODO 兼容 type 属性 ，后续会废弃
			if(type) return
			this.showPopup = true
			this.showTrans = true
		}
	}
}
</script>
<style lang="scss" scoped>
.uni-popup {
	position: fixed;
	/* #ifndef APP-NVUE */
	z-index: 99;
	/* #endif */
}

.fixforpc-z-index {
	/* #ifndef APP-NVUE */
	z-index: 999;
	/* #endif */
}

.uni-popup__mask {
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	right: 0;
	background-color: $uni-bg-color-mask;
	opacity: 0;
}

.mask-ani {
	transition-property: opacity;
	transition-duration: 0.2s;
}

.uni-top-mask {
	opacity: 1;
}

.uni-bottom-mask {
	opacity: 1;
}

.uni-center-mask {
	opacity: 1;
}

.uni-popup__wrapper {
	/* #ifndef APP-NVUE */
	display: block;
	/* #endif */
	position: absolute;
}

.top {
	/* #ifdef H5 */
	top: var(--window-top);
	/* #endif */
	/* #ifndef H5 */
	top: 0;
	/* #endif */
}

.fixforpc-top {
	top: 0;
}

.bottom {
	bottom: 0;
}

.uni-popup__wrapper-box {
	/* #ifndef APP-NVUE */
	display: block;
	/* #endif */
	position: relative;
	/* iphonex 等安全区设置，底部安全区适配 */
	/* #ifndef APP-NVUE */
	padding-bottom: constant(safe-area-inset-bottom);
	padding-bottom: env(safe-area-inset-bottom);
	/* #endif */
}

</style>
